#ifndef _SMRTU_MODBUS_PORT_RTTHREAD_H_
#define _SMRTU_MODBUS_PORT_RTTHREAD_H_

#include "stdint.h"
#include "string.h"
#include "dev_rtu_mb_base.h"
#include "config_dev_rtu_mb.h"

/*
 * mb on rtthread
 */
#if SMRTU_MODBUS_RTTHREAD
/*
 *dev_rtu_mb_init
 */
int dev_rtu_mb_init(dev_rtu_mb_t* smb, uint8_t core_type, void* port);
dev_rtu_mb_t* dev_rtu_mb_create(uint8_t core_type, void* port);

/*
 *mb port rtthread device
 */
#if SMRTU_MODBUS_RTTHREAD_USE_DEVICE

#include <rtthread.h>
#include <rtdevice.h>

typedef struct dev_rtu_dev_rtu_mb_port_rtdevice dev_rtu_dev_rtu_mb_port_rtdevice_t;

struct dev_rtu_dev_rtu_mb_port_rtdevice
{
    struct _dev_rtu_mb_port base;
    struct serial_configure serial_config;
    const char* device_name;
    struct rt_device* device;
    struct rt_semaphore rx_sem;
    rt_size_t rx_size;
    int oflag;
    int (*rts_set)(int on);
};

dev_rtu_dev_rtu_mb_port_rtdevice_t* dev_rtu_mb_port_rtdevice_get(dev_rtu_mb_t* smb);

int dev_rtu_mb_port_rtdevice_init(dev_rtu_dev_rtu_mb_port_rtdevice_t* port, const char* device_name);
int dev_rtu_mb_port_rtdevice_deinit(dev_rtu_dev_rtu_mb_port_rtdevice_t* port);

dev_rtu_dev_rtu_mb_port_rtdevice_t* dev_rtu_mb_port_rtdevice_create(const char* device_name);
int dev_rtu_mb_port_rtdevice_delete(void* port);

int dev_rtu_mb_dev_rtu_set_serial_rts(dev_rtu_mb_t* smb, int (*rts_set)(int on));
int dev_rtu_mb_dev_rtu_set_serial_name(dev_rtu_mb_t* smb, const char* device_name);
int dev_rtu_mb_dev_rtu_set_serial_config(dev_rtu_mb_t* smb, struct serial_configure* serial_config);
int dev_rtu_mb_dev_rtu_set_oflag(dev_rtu_mb_t* smb, int oflag);

#endif

/*
 *mb port rtthread socket
 */
#if SMRTU_MODBUS_RTTHREAD_USE_SOCKET

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#if defined(RT_USING_LIBC) || defined(RT_USING_MINILIBC) || defined(RT_LIBC_USING_TIME)
#include <sys/time.h>
#include <sys/errno.h>
#endif

/* support both enable and disable "SAL_USING_POSIX" */
#if defined(RT_USING_SAL)
#include <netdb.h>
#include <sys/socket.h>
#else
#include <lwip/netdb.h>
#include <lwip/sockets.h>
#endif /* RT_USING_SAL */

#include "ipc/ringbuffer.h"

typedef struct dev_rtu_dev_rtu_mb_port_rtsocket dev_rtu_dev_rtu_mb_port_rtsocket_t;

struct dev_rtu_dev_rtu_mb_port_rtsocket
{
    struct _dev_rtu_mb_port base;
    int32_t socket_fd;
    int devicemode;
    const char* hostname;
    const char* hostport;

    struct rt_ringbuffer rx_ringbuff;
    uint8_t rx_temp[256];
    uint8_t rx_ringbuff_pool[256];
};

int dev_rtu_mb_tcp_status(dev_rtu_mb_t* smb);
int dev_rtu_mb_tcp_disconnect(dev_rtu_mb_t* smb);
int dev_rtu_mb_tcp_connect(dev_rtu_mb_t* smb);
int dev_rtu_mb_tcp_listen(dev_rtu_mb_t* smb, int max_connection);
int dev_rtu_mb_tcp_accept(dev_rtu_mb_t* smb, int socket_fd);

int dev_rtu_mb_tcp_get_socket(dev_rtu_mb_t* smb);
int dev_rtu_mb_tcp_set_socket(dev_rtu_mb_t* smb, int socket);
int dev_rtu_mb_tcp_set_socket_block(dev_rtu_mb_t* smb, int isblock);

dev_rtu_dev_rtu_mb_port_rtsocket_t* dev_rtu_mb_port_rtsocket_get(dev_rtu_mb_t* smb);

int dev_rtu_mb_port_rtsocket_init(dev_rtu_dev_rtu_mb_port_rtsocket_t* port, int devicemode, char* hostname, char* hostport);
int dev_rtu_mb_port_rtsocket_deinit(dev_rtu_dev_rtu_mb_port_rtsocket_t* port);

dev_rtu_dev_rtu_mb_port_rtsocket_t* dev_rtu_mb_port_rtsocket_create(int devicemode, char* hostname, char* hostport);
int dev_rtu_mb_port_rtsocket_delete(void* port);

#endif

#endif /* SMRTU_MODBUS_RTTHREAD */

#endif /* _SMRTU_MODBUS_RTTHREAD_H_ */
